/**
 * 认证授权
 * @author 木人心
 * @version 2.0.0
 */
import { getUserInfoAPI } from '@/api/system'
import { UserInfo } from '@typings/user'
import { authorizationConfig } from '@utils/authorization/config'
import { getToken, removeToken, setToken } from '@utils/authorization/token'
import { useAppStore } from '@/pinia'

export default class Authorization {
  /**
   * 获取令牌
   */
  static get token () {
    return getToken()
  }

  /**
   * 设置令牌
   * @param value
   */
  static setToken = setToken

  /**
   * 清除令牌
   */
  static removeToken () {
    removeToken()
  }

  /**
   * 重新加载用户信息
   */
  static reloadUser () {
    return new Promise<UserInfo>((resolve, reject) => {
      getUserInfoAPI().then((res) => {
        res.result().then((rdata) => {
          const userInfo = rdata.data as UserInfo
          userInfo.role = ''
          userInfo.permission = new Set<string>()
          userInfo._phone = userInfo.phone.replace(/^(\d{3})\d+(\d{4})$/, '$1****$2')
          useAppStore().setUserInfo(userInfo)
          resolve(userInfo)
        }).catch((e) => {
          this.removeToken()
          reject(e)
        })
      }).catch((e) => {
        this.removeToken()
        reject(e)
      })
    })
  }

  /**
   * 异步获取用户信息，优先使用本地存储用户信息
   */
  static get asyncUser (): Promise<UserInfo> {
    return new Promise((resolve) => {
      const userInfo = Authorization.user
      if (!userInfo.id && this.token) {
        this.reloadUser().then((userInfo) => {
          resolve(userInfo)
        }).catch(() => {
          resolve(userInfo)
        })
      } else {
        resolve(userInfo)
      }
    })
  }

  /**
   * 获取本地存储的用户信息
   */
  static get user (): UserInfo {
    return useAppStore().userInfo
  }

  /**
   * 已认证成功状态
   */
  static get isAuthenticated (): boolean {
    return !!this.token && !!this.user.id
  }

  /**
   * 授权（许可）校验
   * 验证当前登录的用户是否满足参数中的权限（角色）规则
   * @param permission 权限（许可）Id
   * @param role 角色Id
   */
  static authorizedCheck (permission: string | number | (string | number)[] = '', role: string[] = []) {
    // 如果访问的内容不需要权限，允许访问
    if (!permission && !role.length) return true
    const user: UserInfo = this.user
    // 否则需要认证，如果没有认证，不允许访问
    if (!this.isAuthenticated) return false
    // 如果角色是超级管理员，允许访问
    if (user.role === authorizationConfig.administratorRoleID) return true
    // 如果用户的角色是许可的角色，允许访问
    if (role.includes(user.role)) return true
    // 如果用户有许可的权限， 允许访问，否则不允许访问
    if (Array.isArray(permission)) {
      for (let i = 0, len = permission.length; i < len; i++) {
        if (user.permission.has(permission[i].toString())) return true
      }
      return false
    } else {
      return user.permission.has(permission.toString())
    }
  }
}
